import pygtk, math, pickle,os,sys
pygtk.require('2.0')
import gtk, gtk.glade

class gtkApp:
    appDir = os.path.dirname(os.path.realpath(__file__))+os.sep
    mainGladeFile = appDir+"main.glade"
    #mainGladeFile = "main.glade"
    finished = 0
    def __init__(self, loadFile = None):
        # initialize the list
        self.listItems = []
        
        self.wTree = gtk.Builder()
        self.wTree.add_from_file(self.mainGladeFile)
        self.table = self.wTree.get_object('liststore1')
        self.treeView= self.wTree.get_object('treeview1')
    
        self.window = self.wTree.get_object('window1')
        
        # set the callback dictionary and connect it
        self.callbacks = {
                          "on_button1_clicked": lambda data: self.wTree.get_object('window2').show_all() ,
                          "on_exit_button_clicked": lambda data: self.wTree.get_object('exit_confirm_window').show_all() ,
                          "on_button1_pressed": lambda data: self.wTree.get_object("button1")
                                                                    .set_label("Loading..."),
                          "on_button1_released": lambda data: self.wTree.get_object("button1")
                                                                    .set_label("Joc Nou"),
                          "on_button3_released": self.onPlayerSubmit,
                          "save_game": self.onSaveGame,
                          "load_game": self.onLoadGame,
                          "confirm_save_game": self.onConfirmSaveGame,
                          "confirm_load_game": self.onConfirmLoadGame,
                          "on_exit_no_released": lambda data: self.wTree.get_object('exit_confirm_window').hide(),
                          "on_exit_yes_released": gtk.main_quit,
                          }
        self.wTree.connect_signals(self.callbacks)
        # if we opened the game from a savegame or from command line
        if loadFile != None:
            self.onConfirmLoadGame(None, filename = loadFile)
    def getEditableRenderer(self, callback, col):
        editableRenderer = gtk.CellRendererText()
        editableRenderer.set_property('editable', True)
        editableRenderer.connect('edited', callback, col)
        return editableRenderer
    def fillTableColumns(self):
        """
        Sets the table columns as we can't do that from glade
        """
        
        joc = gtk.TreeViewColumn('Joc', gtk.CellRendererText()
            , text=0)
        self.treeView.append_column(joc)
        licitat = []
        castigat = []
        pos = 0
        for jucator in self.players:
            pos += 1
            licitat.append(gtk.TreeViewColumn(self.players[len(licitat)]+' Licitate', 
                                              self.getEditableRenderer(self.doEdit, pos),
                                              text=pos))
                                              
            pos += 1
            castigat.append(gtk.TreeViewColumn(self.players[len(castigat)]+' Castigate', 
                                               self.getEditableRenderer(self.doEdit, pos),
                                               text=pos))
            self.treeView.append_column(licitat[-1])
            self.treeView.append_column(castigat[-1])
        self.licitatCol = licitat
        self.castigatCol = castigat
        self.jocCol= joc
       

    def fillTableData(self, table):
        # nr de jucatori * 8 jocuri
                
        for i in xrange(1,9):
            for j in xrange(1,len(self.players)+1):
                table.append([i]+[None]*2*len(self.players)+[None]*self.debris)
        # capatul de tabel
        table.append([None]+['Scor: ',0]*len(self.players)+[None]*self.debris)
    def computeScore(self, column):
        score = 0
        used = 0
        for row in self.table:
            try:
                castigat = int(row[column])
                licitat = int(row[column-1])
            except:
                continue
            if licitat == castigat:
                score += 5+castigat
            else:
                score -= int(math.fabs(licitat - castigat))
            used += 1
        self.table[-1][column] = str(score)
        
    def autosave(self):
        self.onConfirmSaveGame(None, self.appDir+'autosave.whist')
        
    def _(self,obj):
        return self.wTree.get_object(obj)
    ######### HERE START THE CALLBACKS #########

    def doEdit(self, cell, position, value, col):
        if value=='' or int(position) == 24 or int(col) == 0 or int(value)>int(self.table[position][0]):
            return True
        try:
            self.autosave()
            self.table[position][col] = int(value)
            # now we update the score if requirements are met
            if col%2 == 0 and self.table[position][col-1]!=None:
                self.computeScore(col)
        except: 
            pass
    def onPlayerSubmit(self, data):
        playerList = self.wTree.get_object('players').get_text()
        self.players = playerList.split(',')
        if len(self.players) < 3 or len(self.players) > 8:
            return False
        self.table.clear()
        #self.treeView.
        try:
            for col in self.licitatCol:
                self.treeView.remove_column(col)
            for col in self.castigatCol:
                self.treeView.remove_column(col)
            self.treeView.remove_column(self.jocCol)
        except:
            pass
        self.wTree.get_object('window2').hide_all()
        
        # debris number is the number of empty cells to be added to the
        # row appending, and is equal to 17(which is the max number) - number of used cells
        self.debris = 17-(2*len(self.players)+1)
        self.fillTableColumns()
        self.fillTableData(self.table)
        
        self.window.show_all()
    def onSaveGame(self, data):
        self.wTree.get_object('filesave').show_all()
        
        
    def onConfirmSaveGame(self, data, filename=None):
        gameTable = []
        for row in self.table:
            gameTable.append([])
            for cell in row:
                gameTable[-1].append(cell)
        game = (self.players, gameTable)
        if filename==None:
            filename = self._('filesave').get_filename()
        # add extension .whist if not used
        if filename[-6:] != '.whist':
            filename = filename + '.whist'
            
        pickle.dump(game, open(filename,'w+'))
        self.wTree.get_object('filesave').hide()
    
    def onLoadGame(self, data):
        self.wTree.get_object('fileload').show_all()
    
    def onConfirmLoadGame(self, data, filename=None):
        # load data from pickle
        if filename == None:
            game = pickle.load(open(self.wTree.get_object('fileload').get_filename(),'r'))
        else:
            game = pickle.load(open(filename,'r'))
        self.players, gameTable = game
        # remove columns and empty table
        try:
            for col in self.licitatCol:
                self.treeView.remove_column(col)
            for col in self.castigatCol:
                self.treeView.remove_column(col)
            self.treeView.remove_column(self.jocCol)
            self.table.clear()
        except:
            pass
        # insert columns
        self.fillTableColumns()
        # insert data
        for row in gameTable:
            self.table.append(row)
        self.wTree.get_object('fileload').hide()
        
                
    ######### HERE END THE CALLBACKS ###########
    def main(self):
        self.wTree.get_object('window1').show_all()
        gtk.main()
